﻿using BigEgg.Framework.Foundation;
using BigEgg.Framework.UnitTesting;
using FMStudio.Documents.TemplateDocument.Models;
using FMStudio.Documents.TemplateDocument.Properties;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Xml.Linq;
using System.Linq;

namespace FMStudio.Documents.TemplateDocument.Test.Models
{
    [TestClass]
    public class FolderTest
    {
        [TestMethod]
        public void GeneralFolderTest()
        {
            Folder folder = new Folder("NewFolder");

            Assert.AreEqual("NewFolder", folder.Name);
            Assert.AreEqual("NewFolder", folder.TargetFolderName);
            Assert.IsNotNull(folder.Items);
            Assert.AreEqual(0, folder.Items.Count);

            Assert.AreEqual("", folder.Validate());
        }

        [TestMethod]
        public void PropertiesWithNotification()
        {
            Folder folder = new Folder("NewFolder");

            AssertHelper.PropertyChangedEvent(folder, x => x.Name, () => folder.Name = "FolderName");
            Assert.AreEqual("FolderName", folder.Name);

            AssertHelper.PropertyChangedEvent(folder, x => x.TargetFolderName, () => folder.TargetFolderName = "TargetFolderName");
            Assert.AreEqual("TargetFolderName", folder.TargetFolderName);

            AssertHelper.PropertyChangedEvent(folder, x => x.Items,
                () => folder.Items.Add(new Folder("SomeFolder")));
            Assert.AreEqual(1, folder.Items.Count);
        }

        [TestMethod]
        public void ItemsTest()
        {
            Folder folder = new Folder("NewFolder");
            Assert.IsNotNull(folder.Items);

            folder.Items.Add(new Folder("NewFolder"));
            folder.Items.Add(new ProjectItem("NewDocument"));
            Assert.AreEqual(2, folder.Items.Count);

            AssertHelper.PropertyChangedEvent(folder, x => x.Items, () => folder.Items.Add(new Folder("NewFolder2")));
            Assert.AreEqual(3, folder.Items.Count);
        }

        [TestMethod]
        public void NameValidationTest()
        {
            Folder folder = new Folder("NewFolder");

            folder.Name = null;
            Assert.IsNull(folder.Name);
            Assert.AreEqual(Resources.FolderNameMandatory, folder.Validate("Name"));

            folder.Name = "";
            Assert.AreEqual("", folder.Name);
            Assert.AreEqual(Resources.FolderNameMandatory, folder.Validate("Name"));

            folder.Name = "FolderName";
            Assert.AreEqual("", folder.Validate("Name"));
        }

        [TestMethod]
        public void TargetFolderNameValidationTest()
        {
            Folder folder = new Folder("NewFolder");

            folder.TargetFolderName = null;
            Assert.IsNull(folder.TargetFolderName);
            Assert.AreEqual(Resources.FolderTargetFolderNameMandatory, folder.Validate("TargetFolderName"));

            folder.TargetFolderName = "";
            Assert.AreEqual("", folder.TargetFolderName);
            Assert.AreEqual(Resources.FolderTargetFolderNameMandatory, folder.Validate("TargetFolderName"));

            folder.TargetFolderName = "FolderName";
            Assert.AreEqual("", folder.Validate("TargetFolderName"));
        }

        [TestMethod]
        public void SerializationTest()
        {
            Folder folder = new Folder("NewFolder");
            folder.TargetFolderName = "TargetFolder";
            Folder folder2 = new Folder("Folder");
            ProjectItem item1 = new ProjectItem("Item1");
            item1.TargetFileName = "NewItem1";
            item1.ReplaceParameters = true;
            ProjectItem item2 = new ProjectItem("Item2");
            item2.TargetFileName = "NewItem2";

            folder2.Items.Add(item1);
            folder.Items.Add(folder2);
            folder.Items.Add(item2);

            Assert.AreEqual("NewFolder", folder.Name);
            Assert.AreEqual("TargetFolder", folder.TargetFolderName);
            Assert.AreEqual(2, folder.Items.Count);

            XElement element = folder.ObjectToXElement();
            Folder newFolder = element.XElementToObject<Folder>();

            Assert.AreEqual(folder.Name, newFolder.Name);
            Assert.AreEqual(folder.TargetFolderName, newFolder.TargetFolderName);
            Assert.AreEqual(folder.Items.Count, newFolder.Items.Count);

            Folder newFolder2 = newFolder.Items.First(x => x is Folder) as Folder;
            Assert.AreEqual(folder2.Name, newFolder2.Name);
            Assert.AreEqual(folder2.TargetFolderName, newFolder2.TargetFolderName);
            Assert.AreEqual(folder2.Items.Count, newFolder2.Items.Count);


            XElement newElement = new XElement("Folder");
            newElement.SetAttributeValue("Name", "NewFolder");
            newElement.SetAttributeValue("TargetFolderName", "TargetFolder");
            XElement folder2XML = new XElement("Folder");
            folder2XML.SetAttributeValue("Name", "Folder");
            folder2XML.SetAttributeValue("TargetFolderName", "Folder");
            folder2XML.Add(item1.ObjectToXElement());
            newElement.Add(folder2XML);
            newElement.Add(item2.ObjectToXElement());

            newFolder = newElement.XElementToObject<Folder>();

            Assert.AreEqual(folder.Name, newFolder.Name);
            Assert.AreEqual(folder.TargetFolderName, newFolder.TargetFolderName);
            Assert.AreEqual(folder.Items.Count, newFolder.Items.Count);

            newFolder2 = newFolder.Items.First(x => x is Folder) as Folder;
            Assert.AreEqual(folder2.Name, newFolder2.Name);
            Assert.AreEqual(folder2.TargetFolderName, newFolder2.TargetFolderName);
            Assert.AreEqual(folder2.Items.Count, newFolder2.Items.Count);
        }
    }
}
